-- Top view da CPU Z80
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
USE ieee.numeric_std.ALL;
use work.definicoes_gerais.all;

entity processador_top is
    Port ( ADDRESS : out  STD_LOGIC_VECTOR ((num_bits - 1) downto 0);  -- 32 bits de endereco Dados/Codigo
           DATA : inout  STD_LOGIC_VECTOR ((num_bits - 1) downto 0);   -- 32 bits Dados/Codigo
           RESET : in  STD_LOGIC;								 -- 
           CLK : in  STD_LOGIC;
           BUSRQ : in  STD_LOGIC;           
           WAIT_S : in  STD_LOGIC;
           M1 : out  STD_LOGIC;
           MREQ : out  STD_LOGIC;
           WR : out  STD_LOGIC;
           RD : out  STD_LOGIC;
           REFSH : out  STD_LOGIC;
           HALT : out  STD_LOGIC;
			  IORQ : inout STD_LOGIC;
           BUSAK : in  STD_LOGIC);
end processador_top;

architecture Behavioral of processador_top is
-- Declaracao do Datapath
COMPONENT data_path is
    generic (num_bits : INTEGER := 32 );
	 Port ( IMEDIATO    : in  STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           WR_ADDR     : in  reg_geral;
           A_RD_ADDR   : in  reg_geral;
           B_RD_ADDR   : in  reg_geral;
			  SEL_IMM_REG : in  STD_LOGIC;
           RESET       : in  STD_LOGIC;
           STO_REG     : in  STD_LOGIC;
           RD_A        : in  STD_LOGIC;
			  RD_B        : in  STD_LOGIC;
           CLK         : in  STD_LOGIC;
           CARRY       : in  STD_LOGIC;
           ALU_FUNC    : in  operadoresALU;
           REG_OUT_1   : out STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
			  REG_OUT_2   : out STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           FLAGS       : out STD_LOGIC_VECTOR (7 downto 0));
end COMPONENT;

-- Declaracao do Control unit
COMPONENT control_unit is
    Port ( RESET          : in     STD_LOGIC;
           CLK            : in     STD_LOGIC;
			  MEM_READ       : out     STD_LOGIC;
			  MEM_WRITE      : out     STD_LOGIC;
           MEM_ADDR       : out    STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           DATA_CODE      : inout  STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           IMEDIATO       : out    STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           SEL_IMM_REG    : out    STD_LOGIC;
           ALU_FUNC       : out    operadoresALU;
           CARRY          : out    STD_LOGIC;
           A_RD_ADDR      : out    reg_geral;
           B_RD_ADDR      : out    reg_geral;
           WR_ADDR        : out    reg_geral;
           RD_A           : out    STD_LOGIC;
           RD_B           : out    STD_LOGIC;
           STO_REG        : out    STD_LOGIC;
           FLAGS          : in     STD_LOGIC_VECTOR (7 downto 0);
			  DATAPATH_OUT_1 : in     STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           DATAPATH_OUT_2 : in     STD_LOGIC_VECTOR ((num_bits - 1) downto 0));
end COMPONENT;
signal IMM : STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
signal DATAPATH_OUT_1 : STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
signal DATAPATH_OUT_2 : STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
signal FLAGS : STD_LOGIC_VECTOR (7 downto 0);
signal IMM_REG_SEL : STD_LOGIC;
signal CARRY : STD_LOGIC;
signal RD_A : STD_LOGIC;
signal RD_B : STD_LOGIC;
signal STO_REG : STD_LOGIC;
signal ALU_FUNC : operadoresALU;
signal A_RD_ADDR : reg_geral;
signal B_RD_ADDR : reg_geral;
signal WR_ADDR : reg_geral;

begin
	control_unit_0 : component control_unit PORT MAP (
		RESET          => RESET,
		CLK            => CLK ,
		MEM_READ       => RD ,
		MEM_WRITE      => WR ,
		MEM_ADDR       => ADDRESS ,
		DATA_CODE      => DATA ,
		IMEDIATO       => IMM ,
		SEL_IMM_REG    => IMM_REG_SEL,
		ALU_FUNC       => ALU_FUNC,
		CARRY          => CARRY,
		A_RD_ADDR      => A_RD_ADDR,
		B_RD_ADDR      => B_RD_ADDR,
		WR_ADDR        => WR_ADDR,
		RD_A           => RD_A,
		RD_B           => RD_B,
		STO_REG        => STO_REG,
		FLAGS          => FLAGS,
		DATAPATH_OUT_1 => DATAPATH_OUT_1,
		DATAPATH_OUT_2 => DATAPATH_OUT_2
	);
	
	datapath_0 : component data_path PORT MAP (
		IMEDIATO    => IMM,
		WR_ADDR     => WR_ADDR,
		A_RD_ADDR   => A_RD_ADDR,
		B_RD_ADDR   => B_RD_ADDR,
		SEL_IMM_REG => IMM_REG_SEL,
		RESET       => RESET,
		STO_REG     => STO_REG,
		RD_A        => RD_A,
		RD_B        => RD_B,
		CLK         => CLK,
		CARRY       => CARRY,
		ALU_FUNC    => ALU_FUNC,
		REG_OUT_1   => DATAPATH_OUT_1,
		REG_OUT_2   => DATAPATH_OUT_2,
		FLAGS       => FLAGS
	);

end Behavioral;

